const express = require("express");
const fs = require("fs");
const path = require("path");
const OSS = require("ali-oss");
const multer = require("multer");
const { Client } = require("./main");
const fetch = require("node-fetch");
const cors = require("cors");
const app = express();

app.use(cors());
app.use(express.json());

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = "uploads/";
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir);
    }
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + "-" + Math.round(Math.random() * 1e9);
    cb(
      null,
      file.fieldname + "-" + uniqueSuffix + path.extname(file.originalname)
    );
  },
});

const upload = multer({
  storage,
  limits: {
    fileSize: 10 * 1024 * 1024, // 限制10MB
  },
});

// 配置 OSS 客户端
const client = new OSS({
  region: "oss-cn-beijing", // 您 Bucket 所在的地域
  accessKeyId: "LTAI5t7EX6ki2crvDwzAhcEn",
  accessKeySecret: "PvsHZXCAJLyn0NMOvNurICrjOGFCEk",
  bucket: "ceshigpx",
});

/**
 * 上传文件到OSS
 * @param {string} objectName OSS存储的文件名
 * @param {string} filePath 本地文件路径
 */
async function uploadFile(objectName, filePath) {
  try {
    const result = await client.put(objectName, filePath);
    return result;
  } catch (err) {
    throw err;
  }
}

// 文件上传/修改接口
app.post("/upload", upload.single("file"), async (req, res) => {
  try {
    const checked = req.body.checked;
    // 获取元数据
    const { originalname, mimetype, size } = req.file;
    // 使用示例
    const { url } = await uploadFile("contentImage.jpg", req.file.path);
    const content = await Client.main(url);
    const res1 = await startToJson(content, checked);
    console.log("res1", res1);
    if (checked == "true") {
      res.json({ ...res1, success: true });
    } else {
      res.json({ value: res1, success: true });
    }
  } catch (error) {
    console.error("文件上传错误:", error);

    res.status(500).json({
      error: "文件处理失败",
      message: error.message,
    });
  }
});

app.post("/postcontent", async (req, res) => {
  const { value, checked } = req.body; // 从请求体中获取数据
  const res1 = await startToJson(value, checked);
  if (checked == "true") {
    res.json({ ...res1, success: true });
  } else {
    res.json({ value: res1, success: true });
  }
});

let system_prompt =
  '你是一个专业的订单处理AI，请按照以下规则处理给定的的采购单文本：1. 核心任务：从杂乱文本中提取商品信息，生成结构化JSON 2. 必须提取的字段：- 款号（识别最长连续数字序列作为款号，款号，只有可能是数字，可能是4位5位6位的数字，款式 5位数的居多 6位数的必须是8开头的纯数字）- 颜色（中文颜色名称，有一个区间，不在区间的显示为 无法识别 ,区间为： 棕色,图色,棕拼杏色,棕褐色,紫色,紫罗兰,紫红色,砖红色,中蓝色,枣红色,荧光绿,银色,银灰色,银白色,燕麦色,烟灰色,锈红,绣绿,绣金,杏色,杏白色,象牙白,雾霾蓝,驼色,土黄色,图片色,铁锈色,铁锈蓝,天蓝色,碳灰色,炭黑色,水洗灰色,水洗灰,水洗黑色,水洗黑,深棕色,深棕,深色,深蓝色,深蓝,深卡色,深卡其,深咖色,深灰色,深灰,上蓝色,上白色,砂色,沙岩色,乳白色,青色,浅棕色,浅杏色,浅色,浅绿色,浅蓝色,浅蓝,浅卡色,浅卡其色,浅卡其,浅咖色,浅灰色,浅灰蓝,浅灰,浅黄色,浅粉色,浅宝蓝,浅白色,浅白,皮红色,藕粉色,牛仔蓝,牛仔黑,牛油果绿色,柠檬黄,泥黄色,奶茶色,墨绿色,墨绿,摩卡色,米杏色,米色,米咖色,米灰色,米黄,米白色,米白,迷彩色,迷彩绿,迷彩,玫红色,马骝黑,绿色,绿灰色,藍色,蓝色,蓝拼灰色,蓝绿色,蓝灰色,蓝灰,蓝红色,蓝黑色,蓝格纹,蓝格,蓝白色,空青色,卡其色,卡其绿色,卡其绿,卡其灰,卡其,咖色,咖绿色,咖黄色,咖啡色,咖啡,军绿色,军绿,橘色,橘红色,桔色,桔红色,酒红色,焦糖色,焦糖,焦黄,姜黄色,灰杏色,灰色,灰拼黑色,灰拼白,灰绿色,灰蓝色,灰卡色,灰卡其,灰黑色,灰白色,黄色,黄泥色,黄泥蓝色,黄泥,黄格,怀旧蓝,花色,花灰,花白色,湖蓝色,红紫色,红条纹,红色,红绿色,红格,黑紫,黑杏,黑色,黑拼浅灰,黑拼灰色,黑拼灰,黑拼白,黑绿色,黑蓝,黑卡色,黑咖色,黑灰色,黑灰,黑黄,黑红色,黑红,黑粉,黑白色,褐色,荷绿,海军蓝,果绿,瑰红色,高级灰,橄榄色,橄榄绿色,复古色,复古蓝色,复古蓝,复古,粉丝,粉色,粉红色,豆沙绿,豆绿色,豆绿,大红色,瓷灰,纯黑色,纯白色,橙色,茶青色,草绿色,草绿,藏青色,藏青,藏蓝色,藏蓝,彩色,彩蓝色,豹纹色,豹纹,宝蓝色,宝蓝,百花灰,白杏色,白色,白青色,白拼灰,白拼黑色,白蓝色,白兰色,白灰色,白灰迷彩,白灰,白花灰,白黑色,暗绿,暗红,暗粉色 ）- 尺码（服装尺码格式如XL/2XL等，有的裤子的尺码是数字的，L2 XL1 中间如果有空格 要分开解析，有一个区间，不在区间显示 无法识别 区间为：均码,XXXS,XXXL,XXS,XXXXL,XXXXXL,XS,XL,S,M,L,9XL,8XL,7XL,6XL,5XL,4XL,3XL,2XL,10XL,170,160,150,140,130,120,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28）- 数量（尺码后括号内的数字）3. 输出要求：- 只能输出一个JSON数组,返回的content	要是一个JSON数组或者对象(对象的Key指定为"orders")- 每个对象必须包含且仅包含：款号、颜色、尺码、数量四个字段 - 字段名必须使用中文双引号 - 示例格式：[{"款号":"12345","颜色":"黑色","尺码":"XL","数量":1}]4. 处理原则：- 智能识别款号（可能是单独数字或包含字母）- 自动过滤无关文本（地址、编号等）-源数据编号相同如果拆分了，结果也需要拆分一下，源数据多少条，结果就多少条- 遇到多规格组合自动拆分（如 黑色:XL(1)白色:2XL(2) 拆分为两条）- 数量必须转为数字类型（不加引号） 5. 严格禁止： - 任何非JSON内容- 解释性文字 - 字段缺失或多余字段 - 改变原始数据 请直接输出符合要求的JSON数组，不要包含任何其他内容。遇到判断不出来的，就写上这行可能有疑问  让我们人工去写一下';

const sysprompt =
  "你是一个专业的订单处理AI，请按照以下规则处理给定的的采购单文本：1. 核心任务：从杂乱文本中提取商品信息，生成结构化结果 2. 必须提取的字段：- 款号（识别最长连续数字序列作为款号，款号，只有可能是数字，可能是4位5位6位的数字，款式 5位数的居多 6位数的必须是8开头的纯数字）- 颜色（中文颜色名称，有一个区间，不在区间的显示为 无法识别 ,区间为： 棕色,图色,棕拼杏色,棕褐色,紫色,紫罗兰,紫红色,砖红色,中蓝色,枣红色,荧光绿,银色,银灰色,银白色,燕麦色,烟灰色,锈红,绣绿,绣金,杏色,杏白色,象牙白,雾霾蓝,驼色,土黄色,图片色,铁锈色,铁锈蓝,天蓝色,碳灰色,炭黑色,水洗灰色,水洗灰,水洗黑色,水洗黑,深棕色,深棕,深色,深蓝色,深蓝,深卡色,深卡其,深咖色,深灰色,深灰,上蓝色,上白色,砂色,沙岩色,乳白色,青色,浅棕色,浅杏色,浅色,浅绿色,浅蓝色,浅蓝,浅卡色,浅卡其色,浅卡其,浅咖色,浅灰色,浅灰蓝,浅灰,浅黄色,浅粉色,浅宝蓝,浅白色,浅白,皮红色,藕粉色,牛仔蓝,牛仔黑,牛油果绿色,柠檬黄,泥黄色,奶茶色,墨绿色,墨绿,摩卡色,米杏色,米色,米咖色,米灰色,米黄,米白色,米白,迷彩色,迷彩绿,迷彩,玫红色,马骝黑,绿色,绿灰色,藍色,蓝色,蓝拼灰色,蓝绿色,蓝灰色,蓝灰,蓝红色,蓝黑色,蓝格纹,蓝格,蓝白色,空青色,卡其色,卡其绿色,卡其绿,卡其灰,卡其,咖色,咖绿色,咖黄色,咖啡色,咖啡,军绿色,军绿,橘色,橘红色,桔色,桔红色,酒红色,焦糖色,焦糖,焦黄,姜黄色,灰杏色,灰色,灰拼黑色,灰拼白,灰绿色,灰蓝色,灰卡色,灰卡其,灰黑色,灰白色,黄色,黄泥色,黄泥蓝色,黄泥,黄格,怀旧蓝,花色,花灰,花白色,湖蓝色,红紫色,红条纹,红色,红绿色,红格,黑紫,黑杏,黑色,黑拼浅灰,黑拼灰色,黑拼灰,黑拼白,黑绿色,黑蓝,黑卡色,黑咖色,黑灰色,黑灰,黑黄,黑红色,黑红,黑粉,黑白色,褐色,荷绿,海军蓝,果绿,瑰红色,高级灰,橄榄色,橄榄绿色,复古色,复古蓝色,复古蓝,复古,粉丝,粉色,粉红色,豆沙绿,豆绿色,豆绿,大红色,瓷灰,纯黑色,纯白色,橙色,茶青色,草绿色,草绿,藏青色,藏青,藏蓝色,藏蓝,彩色,彩蓝色,豹纹色,豹纹,宝蓝色,宝蓝,百花灰,白杏色,白色,白青色,白拼灰,白拼黑色,白蓝色,白兰色,白灰色,白灰迷彩,白灰,白花灰,白黑色,暗绿,暗红,暗粉色 ）- 尺码（服装尺码格式如XL/2XL等，有的裤子的尺码是数字的，L2 XL1 中间如果有空格 要分开解析，有一个区间，不在区间显示 无法识别 区间为：均码,XXXS,XXXL,XXXXL,XXXXXL,XXS,XS,XL,S,M,L,9XL,8XL,7XL,6XL,5XL,4XL,3XL,2XL,10XL,170,160,150,140,130,120,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28）- 数量（尺码后括号内的数字）3. 输出要求：格式要求:款号 颜色1-尺码/数量、尺码/数量、尺码(1件可不填'/数量”)颜色2-尺码/数量。。。- 输出示例：810417 灰色-L/2、XL、2XL黑色-L  808403 咖色-3XL粉色-M/2、3XL绿色-XL 不同编号自动换行 4. 处理原则：- 智能识别款号（可能是单独数字或包含字母）- 自动过滤无关文本（地址、编号等）-源数据编号相同如果拆分了，结果也需要拆分一下，源数据多少条，结果就多少条 - 遇到多规格组合自动拆分（如 黑色:XL(1)白色:2XL(2) 拆分为两条）- 数量必须转为数字类型（不加引号） 5. 严格禁止：解释性文字 - 字段缺失或多余字段 - 改变原始数据。遇到判断不出来的，就写上这行可能有疑问  让我们人工去写一下";

const startToJson = async (val, checked) => {
  console.log("checked", checked);
  const messages = [
    { role: "system", content: checked == "true" ? system_prompt : sysprompt },
    { role: "user", content: val },
  ];

  const apiKey = "sk-2be49d70cbd248508c5bd75549976633"; // 替换为你的API密钥
  const url = "https://api.deepseek.com/chat/completions";
  const requestBody = {
    model: "deepseek-chat",
    stream: false,
    messages: messages,
  };

  if (checked == "true") {
    requestBody.response_format = {
      type: "json_object",
    };
  }
  console.log("requestBody", requestBody);
  const data = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(requestBody),
  }).then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  });

  const jsonData = data.choices[0].message.content;
  if (checked == "true") {
    const result = JSON.parse(jsonData);
    return result;
  } else {
    return jsonData;
  }
};

app.listen(3000, () => {
  console.log("服务器运行在 http://localhost:3000");
});
